package com.flyee.controller.tools.sandtable {
	
	import alternativa.engine3d.core.*;
	import alternativa.engine3d.loaders.*;
	import alternativa.engine3d.materials.*;
	import alternativa.types.Texture;
	import alternativa.utils.*;
	
	import com.flyee.utils.Map;
	import com.flyee.utils.depot.SandTableDepot;
	
	import flash.display.BitmapData;
	import flash.events.*;
	import flash.net.*;
	
	public class Estate3D extends Mesh {
		
		public var buildingMap : Map = new Map();
		public var planeMap : Map = new Map();
		public var signMap : Map = new Map();
		private var materialMap : Map = new Map();
		private var loadCompleted : Boolean = false;
		public var configCompleted : Boolean = false;
		
		public var service : EstateService;
		
		private var loader3ds : Loader3DS;
		private var loadxml : URLLoader;
		
		public var selectBuilding : Building3D;
		
		public function Estate3D(path : String) { 
			var url:String = path;
			loadxml = new URLLoader();
			loadxml.addEventListener(Event.COMPLETE, completeHandler);
			loadxml.load(new URLRequest(url));
		}
		
		public function completeHandler(event : Event) : void {
			var xml:XML = new XML(event.currentTarget.data as String);
			for each(var x1 : XML in xml.buildings.building){
				var building : Building3D =new Building3D(x1.id.toString(), x1.name.toString(), x1.info.toString(), this);
				buildingMap.put(x1.id.toString(), building);
			}
			for each(var x2 : XML in xml.planes.plane){
				var str : String = x2.id.toString();
				planeMap.put(str, "");
				if(x2.type.toString()=="sign")
					signMap.put(str, "");
			}
			for each(var x3 : XML in xml.textures.texture){
				var object : Object = new Object();
				materialMap.put(x3.id.toString(), SandTableDepot.getInstance().getBitmapData(x3.id.toString()));
			}		
			
			loader3ds = new Loader3DS();
		    //开启平滑处理
		    loader3ds.smooth = true;
		    //材质渲染的精确度---高
		    loader3ds.precision = TextureMaterialPrecision.HIGH;
		    //载入指定路径的3ds文件
		    loader3ds.load(xml.path.toString());  
		    //添加侦听器，当模型载入完毕后运行onLoadingComplete函数
		    loader3ds.addEventListener(Event.COMPLETE, onLoadingComplete);
		    xml = null;
		}

		private function onLoadingComplete(event : Event) : void {
			loadCompleted = true;
			estate3DHandle();
			trace("3ds load complete!");
		}
		
		public function estate3DHandle() : void {
			if(loadCompleted && !configCompleted){
				var objs : Array = new Array();
			    //读取载入的3ds内容并进行焊接处理
			    var object : Mesh;
			    for (var o:* in loader3ds.content.children) {
				    //把载入的数据保存到3D对象object中
				    object = o;
				    //焊接顶点和面
				    weldVerticesAndFaces(object);
				    //将载入、处理好的3D模型加入到场景显示
				    addChild(object);
				    
				    for each(var sface : Surface in object.surfaces.toArray()){
  						var texture : Texture = new Texture(materialMap.get(sface.id));
  						var tMaterial : TextureMaterial = new TextureMaterial(texture);
  						o.setMaterialToSurface(tMaterial, sface);
				    }
				   	
					if(buildingMap.containsKey(object.name)){
						buildingMap.get(object.name).mesh = object;
						buildingMap.get(object.name).initListener();
					}
					if(planeMap.containsKey(object.name)){
						planeMap.put(object.name, object);
						object.rotationZ = 1.5;						
					}
					if(signMap.containsKey(object.name)){
						signMap.put(object.name, object);	
//						object.scaleX = 3;
//						object.scaleY = 3;
//						object.scaleZ = 3;				
					}
			    }
			    this.scaleX = 0.5;
			    this.scaleY = 0.5;
			    this.scaleZ = 0.5;
			    configCompleted = true;
				service.afterEstateLoad(planeMap.values());			
				this.dispatchEvent(new Event(Event.COMPLETE));
				trace("Estate load complete!");
			}
		}
		
		public function modifySignScale(num : Number) : void {
			for each(var obj : Object3D in signMap.values()){
				obj.scaleX = num;
				obj.scaleY = num;
				obj.scaleZ = num;
			}
		}
		 
		//3ds文件数据处理函数，遍历3ds数据将点和面焊接起来
		private function weldVerticesAndFaces(object : Object3D) : void {
			if (object is Mesh) {
			    MeshUtils.autoWeldVertices(Mesh(object), 0.01);
			    MeshUtils.autoWeldFaces(Mesh(object), 0.01, 0.001);
		    }
		    // Running routine for children
		    for (var key:* in object.children) {
		    	weldVerticesAndFaces(key);
		    }
	  	}

	  	public function dispose() : void {
	  		loader3ds.removeEventListener(Event.COMPLETE, onLoadingComplete);
	  		loader3ds.unload();
	  		loader3ds = null;
	  		loadxml.removeEventListener(Event.COMPLETE, completeHandler);
	  		loadxml.close();
	  		loadxml = null;
	  		
	  		if(selectBuilding)
	  			selectBuilding.infoPanel.dispose();
	  		
	  		for each(var building : Building3D in buildingMap.values()){
	  			building.dispose();
	  			building = null;
	  		}
	  		buildingMap.clear();
	  		buildingMap = null;
	  		
	  		signMap.clear();
	  		signMap = null;
	  		
	  		planeMap.clear();
	  		planeMap = null;
	  		
	  		for each(var obj : BitmapData in materialMap.values()) {
	  			obj.dispose();
	  		}
	  		materialMap.clear();
	  		materialMap = null;
	  		for each(var obj3d : Object3D in this.children.toArray()){
	  			this.removeChild(obj3d);
	  		}
	  	
	  		this.service = null;
	  	}

	}
}